package org.pp.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.pp.admin.dto.*;
import org.pp.controller.PageLoader;
import org.pp.core.*;
import org.pp.entity.SysUser;
import org.pp.entity.SysUserRole;
import org.pp.mapper.SysUserMapper;
import org.pp.service.ISysUserRoleService;
import org.pp.service.ISysUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.pp.util.RedisUtil;
import org.pp.vo.AdminSysUserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 系统用户 服务实现类
 * </p>
 *
 * @author haima
 * @since 2024-04-20
 */
@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser>
        implements ISysUserService, PageLoader {

    @Autowired
    ISysUserRoleService userRoleService;

    @Autowired
    RedisUtil redisUtil;

    @Override
    public void passwordReset(SysUserPasswordReset dto) {
        SysUser user = getById(dto.getUserId());
        Assertion.nullThrow(user, "用户不存在");
        Long userId = AdminSessionUtil.getUserId();
        Assertion.equalsThrow(userId, dto.getUserId(), "不能重置自己的密码");
        SysUser editeUser = new SysUser();
        editeUser.setUserId(dto.getUserId());
        editeUser.setPassword(AdminSessionUtil.encrypt(dto.getPassword()));
        updateById(editeUser);
    }

    @Override
    public void statusSwitch(SysUserStatusSwitch dto) {
        SysUser user = getById(dto.getUserId());
        Assertion.nullThrow(user, "用户不存在");
        Long userId = AdminSessionUtil.getUserId();
        Assertion.equalsThrow(userId, dto.getUserId(), "不能修改自己的状态");

        SysUser editeUser = new SysUser();
        editeUser.setUserId(dto.getUserId());
        editeUser.setStatus(AdminConstants.statusActive.equals(user.getStatus()) ?
                AdminConstants.statusDisabled : AdminConstants.statusActive);
        if(AdminConstants.statusDisabled.equals(editeUser.getStatus())){
            redisUtil.delete(AdminSessionUtil.getLoginUserNameKey(dto.getUserId()));
        }
        updateById(editeUser);
    }

    @Override
    public void delete(String ids) {
        List<String> list = Arrays.asList(ids.split(","));
        if(CollectionUtil.isEmpty(list)){
            return;
        }
        List<Long> userIds = listByIds(list).stream().map(SysUser::getUserId).toList();
        if(CollectionUtil.isEmpty(userIds)){
            return;
        }
        removeBatchByIds(userIds);

        //删除用户的角色关联关系
        userRoleService.remove(new LambdaQueryWrapper<SysUserRole>()
                .in(SysUserRole::getUserId, userIds));
        for (Long id : userIds) {
            redisUtil.delete(AdminSessionUtil.getLoginUserNameKey(id));
        }
    }

    @Override
    public Long add(SysUserAdd dto) {
        SysUser exist = getOne(new LambdaQueryWrapper<SysUser>()
                .eq(SysUser::getUserName, dto.getUserName()));
        Assertion.notNullThrow(exist, "用户名已经存在");

        SysUser user = BeanUtil.copyProperties(dto, SysUser.class);
        save(user);
        if (!CollectionUtil.isEmpty(dto.getRoleIds())) {
            //用户角色
            List<SysUserRole> userRoles = new ArrayList<>();
            for (Long roleId : dto.getRoleIds()) {
                SysUserRole userRole = new SysUserRole();
                userRole.setRoleId(roleId);
                userRole.setUserId(user.getUserId());
                userRoles.add(userRole);
            }
            userRoleService.saveBatch(userRoles);
        }
        return user.getUserId();
    }

    @Override
    public void edite(SysUserEdite dto) {
        Long userId = AdminSessionUtil.getUserId();
        Assertion.equalsThrow(dto.getUserId(),userId,"不能编辑自己");
        SysUser editeUser = BeanUtil.copyProperties(dto, SysUser.class);
        Assertion.nullThrow(getById(dto.getUserId()),"用户不存在");
        updateById(editeUser);

        //需要删除的
        List<Long> rmIds = userRoleService.list(new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, dto.getUserId())
                .notIn(!CollectionUtil.isEmpty(dto.getRoleIds()),SysUserRole::getRoleId, dto.getRoleIds())
        ).stream().map(SysUserRole::getUserRoleId).toList();

        if(!CollectionUtil.isEmpty(rmIds)){
            userRoleService.removeBatchByIds(rmIds);
        }
        //目前存在的
        Set<Long> remainIds = userRoleService.list(new LambdaQueryWrapper<SysUserRole>()
                .eq(SysUserRole::getUserId, dto.getUserId())
        ).stream().map(SysUserRole::getRoleId).collect(Collectors.toSet());

        //最后需要添加的
        List<Long> saveIds = dto.getRoleIds().stream().filter(e -> !remainIds.contains(e)).toList();
        List<SysUserRole> userRoles = saveIds.stream().map(e -> {
            SysUserRole userRole = new SysUserRole();
            userRole.setRoleId(e);
            userRole.setUserId(dto.getUserId());
            return userRole;
        }).toList();
        userRoleService.saveBatch(userRoles);
        redisUtil.delete(AdminSessionUtil.getLoginUserNameKey(dto.getUserId()));
    }

    @Override
    public PageBean<AdminSysUserVo> pageList(SysUserPage page) {
        PageHelper.startPage(page.getPageNum(),page.getPageSize());
        List<AdminSysUserVo> list=baseMapper.pageList( page);
        return load(new PageInfo<>(list),AdminSysUserVo.class);
    }

}
